package com.xin.di.uav.applet.config;

import com.xin.di.uav.common.awt.JwtUtil;
import com.xin.di.uav.common.awt.RepeatSubmit;
import com.xin.di.uav.common.awt.SameUrlDataInterceptor;
import com.xin.di.uav.common.enums.ErrorEnum;
import com.xin.di.uav.common.enums.ServicePrefixEnum;
import com.xin.di.uav.common.exception.BusinessException;
import com.xin.di.uav.common.utils.CheckTokenUtil;
import com.xin.di.uav.common.utils.RSAUtils;
import com.xin.di.uav.common.utils.RedisPrefixKey;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
import java.util.Set;

/**
 * @author LTQ
 */
public class JwtInterceptor implements HandlerInterceptor {
    private final static Logger logger = LoggerFactory.getLogger(JwtInterceptor.class);
    @Autowired
    private SameUrlDataInterceptor sameUrlDataInterceptor;
    @Autowired
    private CheckTokenUtil checkTokenUtil;


    @Autowired
    private RedisTemplate redisTemplate;

    public void checkAppKey(String appKey) {
        logger.info("checkAppKey:{}", appKey);
        //解密appKey
        try {
            appKey = RSAUtils.decrypt(appKey);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Set<Object> members = redisTemplate.opsForSet().members(ServicePrefixEnum.RESCUE + RedisPrefixKey.APP_KEY);
        logger.info("members:{}", members);
        Boolean b = members.contains(appKey);
        if (!b) {
            throw new BusinessException(ErrorEnum.APP_KEY_INVALID, "appKey无效！");
        }
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        String requestUri = request.getRequestURI();
//        if (requestUri.contains("home/external")) {
//            //除了支付确认回调，退款确认回调接口都需要检查appKey
//            String appKey = request.getHeader("appKey");
//            if (ObjectUtils.isEmpty(appKey)) {
//                throw new BusinessException("appKey不能为空");
//            }
//            if (!"000004718170608461463552".equals(appKey)) {
//                throw new BusinessException("appKey不合法");
//            }
//        }
        if (requestUri.contains("/sys/")) {
            //从 http 请求头中取出 token
            String token = request.getHeader("token");
            if (token == null || "null".equals(token)) {
                throw new BusinessException(ErrorEnum.NO_TOKEN);
            }

            //校验web的token
            if (token.contains("webToken:")) {
                token = token.replace("webToken:", "");
                checkTokenUtil.checkToken(token);

            } else {

                //验证 token
                JwtUtil.checkSign(token);

                //验证通过后， 这里测试取出JWT中存放的数据
                //获取 token 中的 userId
                String userId = JwtUtil.getUserId(token);
                System.out.println("id : " + userId);
                if (ObjectUtils.isEmpty(userId)) {
                    throw new BusinessException(ErrorEnum.NO_TOKEN, "无 token ，请重新登陆");
                }
                //获取 token 中的其他数据
            }


            //添加防止重复拦截
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                Method method = handlerMethod.getMethod();
                RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
                if (annotation != null) {
                    if (ObjectUtils.isEmpty(request.getSession().getAttribute(request.getRequestURI()))) {
                        request.getSession().setMaxInactiveInterval(annotation.interval());
                        request.getSession().setAttribute(request.getRequestURI(), true);
                    }

                    if (sameUrlDataInterceptor.isRepeatSubmit(request, annotation)) {
                        throw new BusinessException(ErrorEnum.REPEATED_SUBMISSION);
                    }
                }
            }
        }

        return true;
    }
}

